Skip to content

fix(octopus): split IOG slots at the daily low-rate cap boundary - #4644

Merged
springfall2008 merged 2 commits into
mainfrom
fix/octopus-iog-cap-split
Aug 22, 2026
Merged

fix(octopus): split IOG slots at the daily low-rate cap boundary#4644
springfall2008 merged 2 commits into
mainfrom
fix/octopus-iog-cap-split

Conversation

@chalfontchubby

Copy link
Copy Markdown
Collaborator

Summary

  • load_octopus_slots() (car-charging cost accounting) previously flipped a whole multi-block Octopus Intelligent Go dispatch slot to rate_max_base the moment it crossed the octopus_slot_max daily low-rate cap, instead of only pricing the blocks beyond the cap at the higher rate. A single overnight dispatch straddling the cap boundary got fully re-priced at the peak rate instead of being split.
  • Fixes plan showing incorrect monatary values when octopus intelligent car charging running #4624.

Correctness note (not a change in this PR)

On IOG, the car's own 6-hour low-rate allowance is independent of the house's rate - the house still gets the cheap night rate (or a dynamic daytime slot) after the car's cap is used up, while the car's own excess charging reverts to the standard/peak rate regardless of time of day. rate_add_io_slots() (the general "Import p" plan column) already reflects this correctly - it leaves the real underlying tariff rate untouched once the cap is hit, rather than overwriting it. load_octopus_slots() correctly falls back to rate_max_base for the car's own excess kWh, matching that real tariff behaviour, unchanged by this PR.

The one known gap: the plan's shared "Import p" column and tooltips only ever show the house rate for a given time-slot, so when the car is paying the peak rate for excess charging during a period the house shows as cheap, that divergence isn't visible in the UI. That's a display-only follow-up, not a calculation bug, and is being tracked separately rather than folded into this fix.

Test plan

  • ./run_all --quick passes (including the octopus_slots suite and the full random-scenario regression baseline)
  • run_pre_commit clean
  • Verified against the reporter's own debug.yaml replay: plan metric drops from 1226.5736 to 799.8496 with per-slot car charging costs now matching the real dispatch rate

🤖 Generated with Claude Code

load_octopus_slots() previously flipped a whole multi-block dispatch
slot to the max rate the moment it crossed the octopus_slot_max daily
cap, rather than costing only the blocks beyond the cap at the max
rate. This overstated cost/metric whenever a dispatch straddled the
boundary (batpred#4624).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The change directly addresses the reported incorrect repricing behaviour and includes targeted test coverage validating the corrected split-slot costing logic.

Pull request overview

Fixes Octopus Intelligent Go (IOG) car-charging cost accounting by correctly splitting a single dispatch slot when it crosses the daily low-rate block cap, so only the portion beyond the cap is priced at rate_max_base (instead of repricing the entire slot).

Changes:

  • Updated load_octopus_slots() to split partially-over-cap dispatch slots into low-rate and max-rate chunks at the exact cap boundary.
  • Extended the Octopus slot unit tests to assert correct split-slot behaviour and to decouple the overlap/containment test from the low-rate cap logic.
File summaries
File Description
apps/predbat/octopus.py Splits IOG slots at the remaining low-rate block boundary and apportions kWh/cost across the resulting chunks.
apps/predbat/tests/test_octopus_slots.py Adds an expected split-slot case for the cap boundary and isolates the containment-overlap test from cap side-effects.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread apps/predbat/octopus.py Outdated
dp2() on both sides of the cap-boundary split let low_kwh + high_kwh
drift from the original kwh via double-rounding, and made the split
path's kwh precision inconsistent with this function's non-split
chunks, which already carry full-precision kwh (dp2() only applied to
cost/soc downstream). Kept full precision for the split kwh values
instead, matching the rest of the function.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@chalfontchubby

Copy link
Copy Markdown
Collaborator Author

Addressed in 2e9f191: kept full precision for the split kWh values instead of rounding both sides with dp2() - that double-rounding could drift low_kwh + high_kwh from the original kwh, and was inconsistent with this function's non-split chunks, which already carry full-precision kwh (dp2() only applied to cost/soc downstream).

@springfall2008
springfall2008 merged commit 8d3cec1 into main Aug 22, 2026
2 checks passed
@springfall2008
springfall2008 deleted the fix/octopus-iog-cap-split branch August 22, 2026 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

plan showing incorrect monatary values when octopus intelligent car charging running

3 participants